package cn.kennylee.codehub.springmvc.exceptionhandler;

import feign.FeignException;
import feign.codec.DecodeException;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.core.Ordered;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Optional;

/**
 * <p> Feign 异常处理类 </p>
 * <p>Created on 2025/7/21.</p>
 *
 * @author kennylee
 * @since 0.0.1
 */
@RestControllerAdvice
@ConditionalOnClass(name = "feign.FeignException")
@Slf4j
public class FeignExceptionHandler implements Ordered {

    private final ExceptionResultFactory resultFactory;

    public FeignExceptionHandler(ExceptionResultFactory resultFactory) {
        this.resultFactory = resultFactory;
    }

    @PostConstruct
    public void init() {
        log.info("Feign异常处理类已初始化");
    }

    @ExceptionHandler(FeignException.class)
    public ResultModel<Object> handleFeignException(FeignException e) {
        log.error("Feign客户端调用异常", e);

        try {
            Optional<ByteBuffer> responseBody = e.responseBody();
            if (responseBody.isPresent()) {
                ByteBuffer buffer = responseBody.get();
                // 将ByteBuffer转换为字节数组
                byte[] bytes = new byte[buffer.remaining()];
                buffer.get(bytes);

                // 解析响应内容
                String errorContent = new String(bytes, StandardCharsets.UTF_8);
                log.debug("Feign异常响应内容: {}", errorContent);

                return resultFactory.createFailedResult(ResultErrorCode.FEIGN_REMOTE_SERVICE_ERROR, "远程服务调用失败");
            }
        } catch (Exception ex) {
            log.warn("解析Feign响应体异常", ex);
        }

        return resultFactory.createFailedResult(ResultErrorCode.FEIGN_REMOTE_SERVICE_ERROR, "远程服务调用失败: " + e.getMessage());
    }

    @ExceptionHandler(DecodeException.class)
    public ResultModel<Object> handleDecodeException(DecodeException e) {
        log.error("Feign响应解码异常", e);
        return resultFactory.createFailedResult(
            ResultErrorCode.FEIGN_REMOTE_SERVICE_ERROR,
            "远程服务响应解析失败: " + e.getMessage()
        );
    }

    @ExceptionHandler(FeignException.ServiceUnavailable.class)
    public ResultModel<Object> handleFeignServiceUnavailable(DecodeException e) {
        log.error("Feign服务不可用异常", e);
        return resultFactory.createFailedResult(
            ResultErrorCode.FEIGN_REMOTE_SERVICE_ERROR,
            "Feign服务不可用异常: " + e.getMessage()
        );
    }

    @Override
    public int getOrder() {
        return 2;
    }
}
